//
// Created by Administration on 2021/11/29.
//

#include "./myqueue.h"
#include <stdint.h>
#include "string.h"
#include "stdlib.h"
#include <stdio.h>

int SendToBackMyQueue(myQueue q, void *data);
int RevMyqueue(myQueue q, void *data);

myQueue CreateMyqueue(int cap, int onesize){
    myQueue result = (myQueue)queueMalloc(sizeof(struct _myQueue));
    result->data = (void **)queueMalloc(cap * sizeof(void *));
    memset(result->data, 0, cap * sizeof(void *));
    result->len = 0;
    result->capacity = cap;
    result->onesize = onesize;
    result->lock = 0;
    result->SendToBackMyQueue = SendToBackMyQueue;
    result->RevMyqueue = RevMyqueue;
    return result;
}


int LockMyQueue(myQueue q){
    q->lock = 1;
    return 1;
}

int UnlockMyQueue(myQueue q){
    q->lock = 0;
    return 0;
}

int SendToBackMyQueue(myQueue q, void *data){
    if(q->len >= q->capacity){
        return 0;
    }
    if(q->lock){
        return 0;
    }
    LockMyQueue(q);
    *(q->data + q->len) = (uint8_t *)queueMalloc(q->onesize);
    memcpy(*(q->data + q->len), data, q->onesize);
    q->len++;
    UnlockMyQueue(q);
    return 1;
}

int GetMyqueueIsEmpty(myQueue q){
    return q->len;
}

int RevMyqueue(myQueue q, void *data){
    int i;
    if(q->len == 0){
        return 0;
    }
    if(q->lock){
        return 0;
    }
    LockMyQueue(q);
    if(*(q->data)){
        memcpy(data, *(q->data), q->onesize);
    }
    queueFree(*(q->data));
    for(i = 0; i < q->len - 1; i++){
        *(q->data + i) = *(q->data + i + 1);
    }
    *(q->data + q->len - 1) = NULL;
    q->len--;
    UnlockMyQueue(q);
    return 1;
}

int DeleteMyQueue(myQueue q){
    int i;
    for(i = 0; i < q->len; i++){
        queueFree(*(q->data + i));
    }
    queueFree(q->data);
    queueFree(q);
}

/**
 * Test
 * */
void queueTest(void){
    myQueue q = CreateMyqueue(1024, sizeof(CanMsg));
    for(int j = 0; j < 100; j++){
        CanMsg  data;
        data.data = (uint8_t *)malloc(100);
        sprintf(data.data, "hello 0x%x", j);
        data.len = j;
        q->SendToBackMyQueue(q, &data);
        printf("queue len is : %d\n", q->len);
    }
    for(int j = 0; j < 20; j++){
        CanMsg  data;
        data.data = (uint8_t *)malloc(100);
        sprintf(data.data, "hello 0x%x", j);
        data.len = j;
        if(!q->SendToBackMyQueue(q, &data)){
        }
        printf("queue len is : %d\n", q->len);
        CanMsg  getdata2;
        if( q->RevMyqueue(q, &getdata2)) {
//            printf("get data is %d \t %s\n", getdata2.len, getdata2.data);
            printf("queue len is : %d\n", q->len);
            free(getdata2.data);
        }
        else
            break;
    }
    printf("----------------------------\n");
    CanMsg  getdata2;
    while(q->RevMyqueue(q, &getdata2)){
        printf("get data is %d \t %s\n", getdata2.len, getdata2.data);
        free(getdata2.data);
    }
    DeleteMyQueue(q);
    printf("finish!!\n");
}

